#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
const long long B = 16;
int lmt;
int a[N];
struct segment_tree{
    struct node{
        int ls,rs,ma,mi,cnt;
        long long sum;
        int stag;
    } nds[N*3];
    int pcnt;
    inline void push_up(int now){
        nds[now].ma = max(nds[nds[now].ls].ma,nds[nds[now].rs].ma);
        nds[now].mi = min(nds[nds[now].ls].mi,nds[nds[now].rs].mi);
        nds[now].sum = nds[nds[now].ls].sum + nds[nds[now].rs].sum;
        nds[now].cnt = nds[nds[now].ls].cnt + nds[nds[now].rs].cnt;
    }
    inline void subd(int now,int l,int r,int x){
        nds[now].stag += x;
        nds[now].sum -= 1ll*nds[now].cnt*x;
        if(!nds[now].ls){
            for(int i = l;i <= r;i++){
                if(nds[now].mi <= a[i] && a[i] <= nds[now].ma){
                    a[i] -= x;
                }
            }
        }
        nds[now].ma -= x;
        nds[now].mi -= x;
    }
    inline void push_down(int now,int l,int r){
        if(nds[now].stag){
            int mid = (l + r)/2;
            subd(nds[now].ls,l,mid,nds[now].stag);
            subd(nds[now].rs,mid+1,r,nds[now].stag);
            nds[now].stag = 0;
        }
    }
    void rc(int now,int l,int r,int L){
        nds[now].ma = 0;
        nds[now].mi = 0x3f3f3f3f;
        nds[now].sum = 0;
        nds[now].cnt = 0;
        for(int i = l;i <= r;i++){
            if(L <= a[i] && a[i] < 1ll*L*B)
            {
                nds[now].ma = max(nds[now].ma,a[i]);
                nds[now].mi = min(nds[now].mi,a[i]);
                nds[now].sum += a[i];
                nds[now].cnt++;
            }
        }
        return;
    }
    void build(int &now,int l,int r,int L){
        now = ++pcnt;
        if(r - l + 1 <= lmt){
            rc(now,l,r,L);
            return;
        }
        int mid = (l + r)/2;
        build(nds[now].ls,l,mid,L);
        build(nds[now].rs,mid+1,r,L);
        push_up(now);
    }
    void sub(int now,int l,int r,int L,int val,vector<pair<int,int>> &chgs){
        if(nds[now].ma < val){
            return;
        }
        if(nds[now].mi > val && nds[now].mi - val >= L){
            subd(now,l,r,val);
            return;
        }
        if(r - l + 1 <= lmt){
            for(int i = l;i <= r;i++){
                if(L <= a[i] && a[i] < 1ll*L*B){
                    if(a[i] > val){
                        a[i] -= val;
                        if(a[i] < L){
                            chgs.push_back(make_pair(i,a[i]));
                        }
                    }
                }
            }
            rc(now,l,r,L);
            return;
        }
        int mid = (l + r)/2;
        push_down(now,l,r);
        sub(nds[now].ls,l,mid,L,val,chgs);
        sub(nds[now].rs,mid+1,r,L,val,chgs);        
        push_up(now);
    }
    void update(int now,int l,int r,int L,int x,int y,int val,vector<pair<int,int>> &chgs){
        if(x <= l && r <= y){
            sub(now,l,r,L,val,chgs);
            return;
        }
        if(r - l + 1 <= lmt){
            nds[now].ma = 0;
            nds[now].mi = 0x3f3f3f3f;
            nds[now].sum = 0;
            nds[now].cnt = 0;
            for(int i = l;i <= r;i++){
                if(a[i] >= L && a[i] < 1ll*L*B){
                    if(x <= i && i <= y)
                    {
                        if(a[i] > val){
                            a[i] -= val;  
                        }
                        if(a[i] < L){
                            chgs.push_back(make_pair(i,a[i]));
                        }
                    }
                    if(a[i] >= L){
                        nds[now].ma = max(nds[now].ma,a[i]);
                        nds[now].mi = min(nds[now].mi,a[i]);
                        nds[now].cnt++;
                        nds[now].sum += a[i];
                    }
                }
            }
            return;
        }
        int mid = (l + r)/2;
        push_down(now,l,r);
        if(x <= mid){
            update(nds[now].ls,l,mid,L,x,y,val,chgs);
        }
        if(mid < y){
            update(nds[now].rs,mid+1,r,L,x,y,val,chgs);
        }
        push_up(now);
    }
    void updatep(int now,int l,int r,int p,int v){
        if(r - l + 1 <= lmt){
            a[p] = v;
            nds[now].sum += v;
            nds[now].ma = max(nds[now].ma,v);
            nds[now].mi = min(nds[now].mi,v);
            nds[now].cnt++;
            return;
        }
        int mid = (l + r)/2;
        push_down(now,l,r);
        if(p <= mid){
            updatep(nds[now].ls,l,mid,p,v);
        }else{
            updatep(nds[now].rs,mid+1,r,p,v);
        }
        push_up(now);
    }
    struct pack{
        int ma,mi;
        long long sum;
        inline pack operator+(pack val){
            return {max(val.ma,ma),min(mi,val.mi),sum + val.sum};
        }
    };
    pack query(int now,int l,int r,int L,int x,int y){
        if(x <= l && r <= y){
            return {nds[now].ma,nds[now].mi,nds[now].sum};
        }
        if(r - l + 1 <= lmt){
            int ma = 0,mi = 0x3f3f3f3f;
            long long su = 0;
            for(int i = max(l,x);i <= min(r,y);i++){
                if(L <= a[i] && a[i] < 1ll*L*B){
                    ma = max(ma,a[i]);
                    mi = min(mi,a[i]);
                    su += a[i];
                }
            }
            return {ma,mi,su};
        }
        push_down(now,l,r);
        int mid = (l + r)/2;
        pack pk = {0,0x3f3f3f3f,0};
        if(x <= mid){
            pk = pk + query(nds[now].ls,l,mid,L,x,y);
        }
        if(mid < y){
            pk = pk + query(nds[now].rs,mid+1,r,L,x,y);
        }
        return pk;
    }
}sg;
int rots[50];
int read(){
    int res = 0;
    char c = getchar_unlocked();
    while(!isdigit(c)){
        c = getchar_unlocked();
    }
    while(isdigit(c)){
        res = res*10 + (c - '0');
        c = getchar_unlocked();
    }
    return res;
}
int main(){
    int n = read();
    int m = read();
    //cerr<<n<<' '<<m<<'\n';
    lmt = 10;
    int ma = 0;
    for(int i = 1;i <= n;i++){
        a[i] = read();
        ma = max(a[i],ma);
    }
    {
        long long L = 1;
        int lg = 0;
        while(L <= ma){
            sg.build(rots[lg],1,n,L);
            L *= B;
            lg++;
        }
    }
    int lastans = 0;
    for(int i = 1;i <= m;i++){
        int op;
        op = read();
        if(op == 1){
            int l,r,x;
            l = read()^lastans;
            r = read()^lastans;
            x = read()^lastans;
            //cerr<<op<<' '<<l<<' '<<r<<' '<<x<<'\n';
            if(l > r || max(l,r) > n){
                return 0;
            }
            {
                long long L = 1;
                int lg = 0;
                while(L <= ma){
                    if(L*B > x){
                        vector<pair<int,int>> chg;
                        sg.update(rots[lg],1,n,L,l,r,x,chg);
                        for(pair<int,int> pa : chg){
                            int lg1 = log(pa.second)/log(B);
                            sg.updatep(rots[lg1],1,n,pa.first,pa.second);
                        }
                    }
                    L *= B;
                    lg++;
                }
            }
        }else{
            int l,r;
            l = read()^lastans;
            r = read()^lastans;
            // cerr<<op<<' '<<l<<' '<<r<<'\n';
            if(l > r || max(l,r) > n){
                return 0;
            }
            {
                segment_tree::pack res = {0,0x3f3f3f3f,0};;
                long long L = 1;
                int lg = 0;
                while(L <= ma){
                    res = res + sg.query(rots[lg],1,n,L,l,r);
                    L *= B;
                    lg++;
                }
                printf("%lld %d %d\n",res.sum,res.mi,res.ma);
                //lastans = res.sum&((1<<20) - 1);
            }
        }
    }
    return 0;
}